package bold.deposit.aop;

import bold.deposit.useful.Result;
import bold.storage.core.Page;
import bold.storage.core.Record;
import bold.storage.core.RecordList;
import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 需求  处理返回值 封装成 Result 对象
 * 拦截所有controller
 * <p>
 * Record
 * RecordList
 * Page
 */
@Log4j2
@Aspect
@Component
@Order(2)
public class ReturnAspect {

    private Map<String, Method> methodCache = new ConcurrentHashMap<>();

    @Around("execution(* bold.deposit.*Controller.*(..))")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        Object obj = point.proceed();

        //TODO 返回类型必须为Object
        Class targetClass = point.getTarget().getClass();
        MethodSignature ms = (MethodSignature) point.getSignature();
        Method method = null;
        try {
            String methodSplice = targetClass.getName() + ClassUtils.classNamesToString(ms.getParameterTypes());
            method = methodCache.get(methodSplice);
            if (method == null) {
                //注意方法 修饰符 存在报错
                method = targetClass.getDeclaredMethod(ms.getName(), ms.getParameterTypes());
                methodCache.put(methodSplice, method);
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

        if (method.getReturnType() != Object.class) {
            return obj;
        }

        Result result = new Result();
        result.setCode(200);
        if (obj == null) {
            result.setCode(404);
            result.setMsg(Result.map.get(404));
        } else if (obj instanceof Page) {
            if (((Page) obj).getTotalRow() <= 0) {
                result.setCode(404);
                result.setMsg(Result.map.get(404));
            } else {
                result.putData(obj);
            }

        } else if (obj instanceof Record) {
            if (((Record) obj).isEmpty()) {
                result.setCode(404);
                result.setMsg(Result.map.get(404));
            } else {
                result.putData(obj);
            }
        } else if (obj instanceof HashMap) {
            if (((HashMap) obj).isEmpty()) {
                result.setCode(404);
                result.setMsg(Result.map.get(404));
            } else {
                result.putData(obj);
            }
        } else if (obj instanceof RecordList) {
            if (((RecordList) obj).size() <= 0) {
                result.setCode(404);
                result.setMsg(Result.map.get(404));
            } else {
                result.putData(obj);
            }
        } else {
            return obj;
        }
        return result;
    }
}
